/*
 ============================================================================
 Name        : hev-main-dialog.c
 Author      : Heiher <admin@heiher.info>
 Version     : 0.0.2
 Copyright   : Copyright (c) 2010 everyone.
 Description : Linkage 802.1x for Unix-like operating system.
 ============================================================================
 */

#include <libnotify/notify.h>

#include "hev-main-dialog.h"
#include "hev-server.h"
#include "hev-config.h"
#include "hev-status-icon.h"

/*#define HEV_MAIN_WINDOW_ICON		"."G_DIR_SEPARATOR_S"res"G_DIR_SEPARATOR_S"linkage-online.png"*/
#define HEV_MAIN_WINDOW_ICON		"/usr/share/icons/linkage-online.png"

static void hev_main_dialog_server_real_state_changed(HevServer * server, gint state, gpointer data);
static gboolean hev_main_dialog_real_delete_event(GtkWidget * widget, GdkEventAny * event);
static void hev_main_dialog_connect_button_real_clicked(GtkButton * button, gpointer data);
static void hev_main_dialog_disconnect_button_real_clicked(GtkButton * button, gpointer data);

#define HEV_MAIN_DIALOG_GET_PRIVATE(obj)	(G_TYPE_INSTANCE_GET_PRIVATE((obj), HEV_TYPE_MAIN_DIALOG, HevMainDialogPrivate))

typedef struct _HevMainDialogPrivate HevMainDialogPrivate;

struct _HevMainDialogPrivate
{
	GObject * server;
	GObject * config;
	GtkWidget * connect_button;
	GtkWidget * disconnect_button;
	GtkWidget * account_name_entry;
	GtkWidget * account_passwd_entry;
	GtkWidget * interface_entry;
	GtkWidget * autoretry_check_button;
	GtkWidget * retrynumber_spin_button;
	GtkWidget * status_label;
	GtkStatusIcon * status_icon;
	NotifyNotification * notification;
};

G_DEFINE_TYPE(HevMainDialog, hev_main_dialog, GTK_TYPE_DIALOG);

static void hev_main_dialog_dispose(GObject * obj)
{
	HevMainDialog * self = HEV_MAIN_DIALOG(obj);
	HevMainDialogPrivate * priv = HEV_MAIN_DIALOG_GET_PRIVATE(self);

	/* notification START */
	if(notify_is_initted() && G_IS_OBJECT(priv->notification))
	{
		g_object_unref(priv->notification);

		priv->notification = NULL;
	}
	/* notification END */

	/* status_icon START */
	if(G_IS_OBJECT(priv->status_icon))
	{
		g_object_unref(priv->status_icon);

		priv->status_icon = NULL;
	}
	/* status_icon END */

	/* server START */
	if(G_IS_OBJECT(priv->server))
	{
		g_object_unref(priv->server);

		priv->server = NULL;
	}
	/* server END */

	/* config START */
	if(G_IS_OBJECT(priv->config))
	{
		g_object_unref(priv->config);

		priv->config = NULL;
	}
	/* config END */

	G_OBJECT_CLASS(hev_main_dialog_parent_class)->dispose(obj);
}

static void hev_main_dialog_finalize(GObject * obj)
{
	HevMainDialog * self = HEV_MAIN_DIALOG(obj);
	HevMainDialogPrivate * priv = HEV_MAIN_DIALOG_GET_PRIVATE(self);

	G_OBJECT_CLASS(hev_main_dialog_parent_class)->finalize(obj);
}

static void hev_main_dialog_class_init(HevMainDialogClass * klass)
{
	GObjectClass * obj_class = G_OBJECT_CLASS(klass);

	obj_class->dispose = hev_main_dialog_dispose;
	obj_class->finalize = hev_main_dialog_finalize;

	GTK_WIDGET_CLASS(klass)->delete_event = hev_main_dialog_real_delete_event;

	g_type_class_add_private(klass, sizeof(HevMainDialogPrivate));
}

static void hev_main_dialog_init(HevMainDialog * self)
{
	HevMainDialogPrivate * priv = HEV_MAIN_DIALOG_GET_PRIVATE(self);
	GtkWidget * vbox = NULL;
	GtkWidget * table = NULL, * widget = NULL;

	gtk_window_set_title(GTK_WINDOW(self), "联创网络认证管理器");
	gtk_window_set_default_size(GTK_WINDOW(self), 300, 180);
	gtk_window_set_icon_from_file(GTK_WINDOW(self), HEV_MAIN_WINDOW_ICON, NULL);
	gtk_container_set_border_width(GTK_CONTAINER(self), 4);

	priv->status_icon = hev_status_icon_new();
	hev_status_icon_set_offline(HEV_STATUS_ICON(priv->status_icon));
	hev_status_icon_set_main_dialog(HEV_STATUS_ICON(priv->status_icon), GTK_WIDGET(self));

	if(notify_is_initted())
	{
		priv->notification = notify_notification_new_with_status_icon("联创网络认证管理器",
				"", "", priv->status_icon);
		notify_notification_set_timeout(priv->notification, 3);
	}

	vbox = gtk_dialog_get_content_area(GTK_DIALOG(self));
	table = gtk_table_new(5, 2, FALSE);
	gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, FALSE, 0);

	priv->account_name_entry = gtk_entry_new();
	widget = gtk_label_new("用户名:");
	gtk_table_attach(GTK_TABLE(table), widget, 0, 1, 0, 1, 0, 0, 0, 0);
	gtk_table_attach_defaults(GTK_TABLE(table), priv->account_name_entry, 1, 2, 0, 1);

	priv->account_passwd_entry = gtk_entry_new();
	gtk_entry_set_visibility(GTK_ENTRY(priv->account_passwd_entry), FALSE);
	widget = gtk_label_new("密　码:");
	gtk_table_attach(GTK_TABLE(table), widget, 0, 1, 1, 2, 0, 0, 0, 0);
	gtk_table_attach_defaults(GTK_TABLE(table), priv->account_passwd_entry, 1, 2, 1, 2);

	priv->interface_entry = gtk_entry_new();
	widget = gtk_label_new("网　卡:");
	gtk_table_attach(GTK_TABLE(table), widget, 0, 1, 2, 3, 0, 0, 0, 0);
	gtk_table_attach_defaults(GTK_TABLE(table), priv->interface_entry, 1, 2, 2, 3);

	widget = gtk_hbox_new(TRUE, 0);
	gtk_table_attach_defaults(GTK_TABLE(table), widget, 0, 2, 3, 4);
	priv->autoretry_check_button = gtk_check_button_new_with_label("自动重连");
	gtk_box_pack_start(GTK_BOX(widget), priv->autoretry_check_button, FALSE, FALSE, 0);

	priv->retrynumber_spin_button = gtk_spin_button_new_with_range(0, 10, 1.0);
	gtk_box_pack_start(GTK_BOX(widget), priv->retrynumber_spin_button, FALSE, FALSE, 0);

	priv->status_label = gtk_label_new("");
	gtk_table_attach_defaults(GTK_TABLE(table), priv->status_label, 0, 2, 4, 5);

	priv->connect_button = gtk_dialog_add_button(GTK_DIALOG(self), "连接", GTK_RESPONSE_NONE);
	g_signal_connect(G_OBJECT(priv->connect_button), "clicked",
			G_CALLBACK(hev_main_dialog_connect_button_real_clicked), self);

	priv->disconnect_button = gtk_dialog_add_button(GTK_DIALOG(self), "断开", GTK_RESPONSE_NONE);
	gtk_widget_set_sensitive(GTK_WIDGET(priv->disconnect_button), FALSE);
	g_signal_connect(G_OBJECT(priv->disconnect_button), "clicked",
			G_CALLBACK(hev_main_dialog_disconnect_button_real_clicked), self);

	gtk_button_box_set_layout(GTK_BUTTON_BOX(gtk_dialog_get_action_area(GTK_DIALOG(self))),
			GTK_BUTTONBOX_SPREAD);

	gtk_widget_show_all(GTK_WIDGET(self));
}

GtkWidget * hev_main_dialog_new(void)
{
	return g_object_new(HEV_TYPE_MAIN_DIALOG, NULL);
}

void hev_main_dialog_set_server(HevMainDialog * self, GObject * server)
{
	HevMainDialogPrivate * priv = NULL;
	GObject * obj = NULL;

	g_return_if_fail(HEV_IS_MAIN_DIALOG(self));
	g_return_if_fail(HEV_IS_SERVER(server));

	priv = HEV_MAIN_DIALOG_GET_PRIVATE(self);

	priv->server = g_object_ref(server);
	g_signal_connect(G_OBJECT(server), "state_changed",
			G_CALLBACK(hev_main_dialog_server_real_state_changed), self);

	g_object_get(G_OBJECT(priv->server), "config", &obj, NULL);
	if(HEV_IS_CONFIG(obj))
	{
		gchar * str = NULL;

		priv->config = g_object_ref(obj);

		str = hev_config_get_account_name(HEV_CONFIG(priv->config));
		gtk_entry_set_text(GTK_ENTRY(priv->account_name_entry), str);
		g_free(str);

		str = hev_config_get_account_passwd(HEV_CONFIG(priv->config));
		gtk_entry_set_text(GTK_ENTRY(priv->account_passwd_entry), str);
		g_free(str);

		str = hev_config_get_general_interface(HEV_CONFIG(priv->config));
		gtk_entry_set_text(GTK_ENTRY(priv->interface_entry), str);
		g_free(str);

		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->autoretry_check_button),
				hev_config_get_general_autoretry(HEV_CONFIG(priv->config)));

		gtk_spin_button_set_value(GTK_SPIN_BUTTON(priv->retrynumber_spin_button),
				hev_config_get_general_retrynumber(HEV_CONFIG(priv->config)));
	}
}

static void hev_main_dialog_server_real_state_changed(HevServer * server, gint state, gpointer data)
{
	HevMainDialog * self = HEV_MAIN_DIALOG(data);
	HevMainDialogPrivate * priv = NULL;

	g_return_if_fail(HEV_IS_MAIN_DIALOG(self));

	priv = HEV_MAIN_DIALOG_GET_PRIVATE(self);

	switch(state)
	{
	case HEV_SERVER_NULL:
		gtk_label_set_text(GTK_LABEL(priv->status_label), "");
		gtk_widget_set_sensitive(priv->connect_button, TRUE);
		gtk_widget_set_sensitive(priv->disconnect_button, FALSE);
		hev_status_icon_set_offline(HEV_STATUS_ICON(priv->status_icon));
		if(notify_is_initted())
		{
			notify_notification_update(priv->notification, "联创网络认证管理器",
					"连接断开！", "notification-network-ethernet-disconnected");
			notify_notification_show(priv->notification, NULL);
		}
		break;
	case HEV_SERVER_FINDING_SERVER:
		gtk_label_set_text(GTK_LABEL(priv->status_label), "正在查找认证服务器 ...");
		gtk_widget_set_sensitive(priv->connect_button, FALSE);
		gtk_widget_set_sensitive(priv->disconnect_button, TRUE);
		break;
	case HEV_SERVER_AUTH_ACCOUNT_NAME:
		gtk_label_set_text(GTK_LABEL(priv->status_label), "正在认证用户名 ...");
		gtk_widget_set_sensitive(priv->connect_button, FALSE);
		gtk_widget_set_sensitive(priv->disconnect_button, TRUE);
		break;
	case HEV_SERVER_AUTH_ACCOUNT_PASSWD:
		gtk_label_set_text(GTK_LABEL(priv->status_label), "正在认证密码 ...");
		gtk_widget_set_sensitive(priv->connect_button, FALSE);
		gtk_widget_set_sensitive(priv->disconnect_button, TRUE);
		break;
	case HEV_SERVER_AUTH_SUCC:
		gtk_label_set_text(GTK_LABEL(priv->status_label), "验证成功，请启动DHCP客户端获得IP地址！");
		gtk_widget_set_sensitive(priv->connect_button, FALSE);
		gtk_widget_set_sensitive(priv->disconnect_button, TRUE);
		hev_status_icon_set_online(HEV_STATUS_ICON(priv->status_icon));
		if(notify_is_initted())
		{
			notify_notification_update(priv->notification, "联创网络认证管理器",
					"验证成功，请启动DHCP客户端获得IP地址！", "notification-network-ethernet-connected");
			notify_notification_show(priv->notification, NULL);
		}
		break;
	case HEV_SERVER_AUTH_FAIL_FINDING_SERVER:
		gtk_label_set_text(GTK_LABEL(priv->status_label), "服务器拒绝请求！");
		gtk_widget_set_sensitive(priv->connect_button, TRUE);
		gtk_widget_set_sensitive(priv->disconnect_button, FALSE);
		hev_status_icon_set_offline(HEV_STATUS_ICON(priv->status_icon));
		if(notify_is_initted())
		{
			notify_notification_update(priv->notification, "联创网络认证管理器",
					"服务器拒绝请求！", "notification-network-ethernet-disconnected");
			notify_notification_show(priv->notification, NULL);
		}
		break;
	case HEV_SERVER_AUTH_FAIL_ACCOUNT_NAME:
		gtk_label_set_text(GTK_LABEL(priv->status_label), "用户名错误！");
		gtk_widget_set_sensitive(priv->connect_button, TRUE);
		gtk_widget_set_sensitive(priv->disconnect_button, FALSE);
		hev_status_icon_set_offline(HEV_STATUS_ICON(priv->status_icon));
		if(notify_is_initted())
		{
			notify_notification_update(priv->notification, "联创网络认证管理器",
					"用户名错误！", "notification-network-ethernet-disconnected");
			notify_notification_show(priv->notification, NULL);
		}
		break;
	case HEV_SERVER_AUTH_FAIL_ACCOUNT_PASSWD:
		gtk_label_set_text(GTK_LABEL(priv->status_label), "密码错误！");
		gtk_widget_set_sensitive(priv->connect_button, TRUE);
		gtk_widget_set_sensitive(priv->disconnect_button, FALSE);
		hev_status_icon_set_offline(HEV_STATUS_ICON(priv->status_icon));
		if(notify_is_initted())
		{
			notify_notification_update(priv->notification, "联创网络认证管理器",
					"密码错误！", "notification-network-ethernet-disconnected");
			notify_notification_show(priv->notification, NULL);
		}
		break;
	case HEV_SERVER_AUTH_FAIL_SUCC:
		gtk_label_set_text(GTK_LABEL(priv->status_label), "服务器断开连接！");
		gtk_widget_set_sensitive(priv->connect_button, TRUE);
		gtk_widget_set_sensitive(priv->disconnect_button, FALSE);
		hev_status_icon_set_offline(HEV_STATUS_ICON(priv->status_icon));
		if(notify_is_initted())
		{
			notify_notification_update(priv->notification, "联创网络认证管理器",
					"服务器断开连接！", "notification-network-ethernet-disconnected");
			notify_notification_show(priv->notification, NULL);
		}
		break;
	case HEV_SERVER_TIMEOUT:
		gtk_label_set_text(GTK_LABEL(priv->status_label), "找不到认证服务器！");
		gtk_widget_set_sensitive(priv->connect_button, TRUE);
		gtk_widget_set_sensitive(priv->disconnect_button, FALSE);
		hev_status_icon_set_offline(HEV_STATUS_ICON(priv->status_icon));
		if(notify_is_initted())
		{
			notify_notification_update(priv->notification, "联创网络认证管理器",
					"找不到认证服务器！", "notification-network-ethernet-disconnected");
			notify_notification_show(priv->notification, NULL);
		}
		break;
	}
}

static gboolean hev_main_dialog_real_delete_event(GtkWidget * widget, GdkEventAny * event)
{
	gtk_main_quit();

	return TRUE;
}

static void hev_main_dialog_connect_button_real_clicked(GtkButton * button, gpointer data)
{
	HevMainDialog * self = HEV_MAIN_DIALOG(data);
	HevMainDialogPrivate * priv = NULL;
	GtkEntryBuffer * buffer = NULL;

	g_return_if_fail(HEV_IS_MAIN_DIALOG(self));

	priv = HEV_MAIN_DIALOG_GET_PRIVATE(self);

	buffer = gtk_entry_get_buffer(GTK_ENTRY(priv->account_name_entry));
	if(0 >= gtk_entry_buffer_get_length(GTK_ENTRY_BUFFER(buffer)))
	{
		GtkWidget * dialog = NULL;

		dialog = gtk_message_dialog_new(GTK_WINDOW(self),
				GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
				GTK_MESSAGE_ERROR,
				GTK_BUTTONS_CLOSE,
				"请输入用户名！");
		gtk_dialog_run(GTK_DIALOG(dialog));
		gtk_widget_destroy(dialog);

		return;
	}

	buffer = gtk_entry_get_buffer(GTK_ENTRY(priv->account_passwd_entry));
	if(0 >= gtk_entry_buffer_get_length(GTK_ENTRY_BUFFER(buffer)))
	{
		GtkWidget * dialog = NULL;

		dialog = gtk_message_dialog_new(GTK_WINDOW(self),
				GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
				GTK_MESSAGE_ERROR,
				GTK_BUTTONS_CLOSE,
				"请输入密码！");
		gtk_dialog_run(GTK_DIALOG(dialog));
		gtk_widget_destroy(dialog);

		return;
	}

	buffer = gtk_entry_get_buffer(GTK_ENTRY(priv->interface_entry));
	if(0 >= gtk_entry_buffer_get_length(GTK_ENTRY_BUFFER(buffer)))
	{
		GtkWidget * dialog = NULL;

		dialog = gtk_message_dialog_new(GTK_WINDOW(self),
				GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
				GTK_MESSAGE_ERROR,
				GTK_BUTTONS_CLOSE,
				"请输入网卡接口名称！");
		gtk_dialog_run(GTK_DIALOG(dialog));
		gtk_widget_destroy(dialog);

		return;
	}

	hev_config_set_account_name(HEV_CONFIG(priv->config),
			gtk_entry_get_text(GTK_ENTRY(priv->account_name_entry)));
	hev_config_set_account_passwd(HEV_CONFIG(priv->config),
			gtk_entry_get_text(GTK_ENTRY(priv->account_passwd_entry)));
	hev_config_set_general_interface(HEV_CONFIG(priv->config),
			gtk_entry_get_text(GTK_ENTRY(priv->interface_entry)));
	hev_config_set_general_autoretry(HEV_CONFIG(priv->config),
			gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->autoretry_check_button)));
	hev_config_set_general_retrynumber(HEV_CONFIG(priv->config),
			gtk_spin_button_get_value(GTK_SPIN_BUTTON(priv->retrynumber_spin_button)));

	if(-1 == hev_server_start(HEV_SERVER(priv->server)))
	{
		GtkWidget * dialog = NULL;

		dialog = gtk_message_dialog_new(GTK_WINDOW(self),
				GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
				GTK_MESSAGE_ERROR,
				GTK_BUTTONS_CLOSE,
				"连接启动失败！");
		gtk_dialog_run(GTK_DIALOG(dialog));
		gtk_widget_destroy(dialog);
	}
}

static void hev_main_dialog_disconnect_button_real_clicked(GtkButton * button, gpointer data)
{
	HevMainDialog * self = HEV_MAIN_DIALOG(data);
	HevMainDialogPrivate * priv = NULL;

	g_return_if_fail(HEV_IS_MAIN_DIALOG(self));

	priv = HEV_MAIN_DIALOG_GET_PRIVATE(self);

	hev_server_stop(HEV_SERVER(priv->server));
}
